package com.chucang.shucang.common.security.feignconfig;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.chucang.shucang.common.base.constant.SecurityConstant;
import com.chucang.shucang.common.base.utils.WebUtil;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Enumeration;

/**
 * @author flitsneak
 * @email flitsneak@gmail.com
 * @date 2022/9/24 19:24
 * @description feign拦截器
 */
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(name = "oauth2.resource.sever.enabled", havingValue = "true")
public class OAuthFeignRequestInterceptor implements RequestInterceptor {
    private final BearerTokenResolver tokenResolver;

    /**
     * 1. 如果使用 非web 请求，header 区别
     * 2. 根据authentication 还原请求token
     *
     * @param template template
     */
    @Override
    public void apply(RequestTemplate template) {
        Collection<String> fromHeader = template.headers().get(SecurityConstant.FROM);
        // 带from 请求直接跳过
        if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(SecurityConstant.FROM_IN)) {
            return;
        }

        // 非web 请求直接跳过
        if (WebUtil.getRequest().isEmpty()) {
            return;
        }
        HttpServletRequest request = WebUtil.getRequest().get();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                template.header(name, values);
            }
        }

        //token复制转交
        String token = tokenResolver.resolve(request);
        if (CharSequenceUtil.isBlank(token)) {
            return;
        }
        template.header(HttpHeaders.AUTHORIZATION, String.format("%s %s", OAuth2AccessToken.TokenType.BEARER, token));

    }
}
